package com.cyl.manager.oms.controller;

import java.time.Duration;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.cyl.config.ecxle.ExcelSysDictOutUtils;
import com.cyl.external.MyEasyExcelUtil;
import com.cyl.h5.domain.form.ApplyRefundForm;
import com.cyl.h5.service.H5OrderService;
import com.cyl.manager.aws.domain.entity.ExportExcel;
import com.cyl.manager.oms.convert.OrderConvert;
import com.cyl.manager.oms.domain.entity.Order;
import com.cyl.manager.oms.domain.form.DealWithAftersaleForm;
import com.cyl.manager.oms.domain.form.DeliverProductForm;
import com.cyl.manager.oms.domain.form.ManagerOrderQueryForm;
import com.cyl.manager.oms.domain.vo.ManagerOrderDetailVO;
import com.cyl.manager.oms.domain.vo.ManagerOrderShopVO;
import com.cyl.manager.oms.domain.vo.ManagerOrderVO;
import com.cyl.manager.oms.domain.vo.OrderOperateHistoryVO;
import com.cyl.manager.oms.mapper.OrderMapper;
import com.cyl.manager.oms.service.AftersaleService;
import com.cyl.manager.oms.service.OrderService;
import com.cyl.manager.ums.domain.entity.Member;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.core.redis.RedisService;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.config.LocalDataUtil;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
/**
 * 订单表Controller
 * 
 * @author zcc
 * @date 2022-12-01
 */
@Api(description ="订单表接口列表")
@RestController
@RequestMapping("/oms/order")
@Slf4j
public class OrderController extends BaseController {
    @Autowired
    private OrderService service;
    @Autowired
    private OrderConvert convert;
    @Autowired
    private RedisService redisService;
    @Autowired
    private AftersaleService aftersaleService;
    
    @Autowired
    private OrderMapper orderMapper;
    
    @Autowired
    private RedisCache redisCache;
    @ApiOperation("查询订单表列表")
    @PreAuthorize("@ss.hasPermi('oms:order:list')")
    @PostMapping("/list")
    public ResponseEntity<Page<ManagerOrderVO>> list(@RequestBody ManagerOrderQueryForm query, Pageable page) {
        Long qrDeptZbjId = SecurityUtils.getDeptZbjId();
        if(qrDeptZbjId!=null) {
        	query.setDeptZbjId(qrDeptZbjId);
        }
        return ResponseEntity.ok(service.selectList(query, page));
    }
    
    @ApiOperation("查询订单表列表的商品总数和销售总额")
    @PreAuthorize("@ss.hasPermi('oms:order:list')")
    @PostMapping("/sum") //返回quantity 和payAmount
    public ResponseEntity<ManagerOrderVO> sum(@RequestBody ManagerOrderQueryForm query, Pageable page) {
        Long qrDeptZbjId = SecurityUtils.getDeptZbjId();
        if(qrDeptZbjId!=null) {
        	query.setDeptZbjId(qrDeptZbjId);
        }
        return ResponseEntity.ok(orderMapper.selectManagerOrderPageSun(query));
    }
    

    @ApiOperation("修改收件人信息")
    @PostMapping("/receiver/update")
    public ResponseEntity<Boolean> updateReceiver(@RequestBody Order order) {
        return ResponseEntity.ok(service.updateReceiver(order));
    }

//    @ApiOperation("导出订单表列表")
//    @PreAuthorize("@ss.hasPermi('oms:order:export')")
//    @Log(title = "订单表", businessType = BusinessType.EXPORT)
//    @GetMapping("/export")
//    public ResponseEntity<String> export(OrderQuery query) {
////        List<Order> list = service.selectList(query, null);
////        ExcelUtil<OrderVO> util = new ExcelUtil<>(OrderVO.class);
////        return ResponseEntity.ok(util.writeExcel(convert.dos2vos(list), "订单表数据"));
//        return null;
//    }
    
    
    
    @PreAuthorize("@ss.hasPermi('oms:order:list')")
    @GetMapping("/getOrderCount") 
    public ResponseEntity<Long> getOrderCount( ManagerOrderQueryForm query) {
        PageRequest pageable =  PageRequest.of(0, 1); 
        Page<ManagerOrderVO> retPage =  service.selectList(query, pageable);
        return ResponseEntity.ok(retPage.getTotalElements());
    }
    
    //@ApiOperation("导出订单表列表")
    @PreAuthorize("@ss.hasPermi('oms:order:export')")
    @Log(title = "订单表", businessType = BusinessType.EXPORT)
    @GetMapping("/export") // @RequestBody
    public ResponseEntity<ExportExcel> export( ManagerOrderQueryForm query) {
        long lockTime = Long.parseLong("9"+DateUtil.format(DateUtil.date(), "yyyyMMddHHssSSS")+ SecurityUtils.getUserId());
        MyEasyExcelUtil<ManagerOrderVO> myEasyExcelUtil = null;
        Long qrDeptZbjId = SecurityUtils.getDeptZbjId();
        String url = "";
       String redisKey = "order_export_conv_key"+qrDeptZbjId;
       String redisValue = "order_export_lock_value" + "_" + lockTime;
       try{
           redisService.lock(redisKey, redisValue, 60*30);
           //设置导出字典
           ExcelSysDictOutUtils.setSysDictMap(ManagerOrderVO.class);
           if(qrDeptZbjId!=null) {
           	query.setDeptZbjId(qrDeptZbjId);
           }
           PageRequest pageable =  PageRequest.of(0, 1); 
           Page<ManagerOrderVO> retPage =  service.selectList(query, pageable);
           long dataSize = retPage.getTotalElements();
           
           ExportExcel exportExcel = new ExportExcel(JSONUtil.toJsonStr(query), "订单表数据普通"+lockTime+".xlsx", "订单数据普通导出", lockTime, dataSize);
           myEasyExcelUtil = new MyEasyExcelUtil<ManagerOrderVO>(ManagerOrderVO.class, exportExcel);
           int pageSize = 2000;
           int leng = myEasyExcelUtil.getLength(dataSize, pageSize);
           for (int i = 0; i < leng; i++) {
               Page<ManagerOrderVO> page =  service.selectList(query, PageRequest.of(i, pageSize),true);
               myEasyExcelUtil.writeList(page.getContent());
		   }
           myEasyExcelUtil.finish();
           return ResponseEntity.ok(exportExcel);
       } catch (Exception e) {
			if(myEasyExcelUtil!=null){
				myEasyExcelUtil.error(e);
			} 
			e.printStackTrace();
		}finally {
		   if(myEasyExcelUtil!=null){
				myEasyExcelUtil.finallyClose();
		   } 
           try {
               redisService.unLock(redisKey, redisValue);
           } catch (Exception e) {
               e.printStackTrace();
           }
          
       }
		return null;
        
    }
    
    
    @PreAuthorize("@ss.hasPermi('oms:order:export')")
    @Log(title = "拆单合并导出", businessType = BusinessType.EXPORT)
    @GetMapping("/exportShop")
    public ResponseEntity<ExportExcel> exportShop(ManagerOrderQueryForm query) {
        long lockTime = Long.parseLong("8"+DateUtil.format(DateUtil.date(), "yyyyMMddHHssSSS")+ SecurityUtils.getUserId());
        MyEasyExcelUtil<ManagerOrderShopVO> myEasyExcelUtil = null;
        Long qrDeptZbjId = SecurityUtils.getDeptZbjId();
        String redisKey = "order_exportdptj_conv_key"+qrDeptZbjId;
        String redisValue = "order_exportdptj_lock_value" + "_" + lockTime;
    	if(query.getPayStartTime()==null && query.getRetStartTime()==null) {
			throw new RuntimeException("支付时间和退款时间必须选择一个");
		}
		if(query.getPayStartTime()!=null) {
			if(Duration.between(query.getPayStartTime(), query.getPayEndTime()).toDays() > 7) {
				throw new RuntimeException("只能导出支付时间7天的数据");
			}
		}
		if(query.getRetStartTime()!=null) {
			if(Duration.between(query.getRetStartTime(), query.getRetEndTime()).toDays() > 31) {
				throw new RuntimeException("只能导出退款时间31天的数据");
			}
		}
       try{
           redisService.lock(redisKey, redisValue, 60*30);
           //设置导出字典
           ExcelSysDictOutUtils.setSysDictMap(ManagerOrderShopVO.class);
           if(qrDeptZbjId!=null) {
           		query.setDeptZbjId(qrDeptZbjId);
           }
           List<ManagerOrderShopVO> retList =  service.selectListByShop(query);
           ExportExcel exportExcel = new ExportExcel(JSONUtil.toJsonStr(query), "拆单合并导出"+lockTime+".xlsx", "拆单合并导出", lockTime, (long)retList.size());
           myEasyExcelUtil = new MyEasyExcelUtil<ManagerOrderShopVO>(ManagerOrderShopVO.class, exportExcel);
           myEasyExcelUtil.writeList(retList);
           myEasyExcelUtil.finish();
           return ResponseEntity.ok(exportExcel);
       } catch (Exception e) {
			if(myEasyExcelUtil!=null){
				myEasyExcelUtil.error(e);
			} 
			e.printStackTrace();
		}finally {
		   if(myEasyExcelUtil!=null){
				myEasyExcelUtil.finallyClose();
		   } 
           try {
               redisService.unLock(redisKey, redisValue);
           } catch (Exception e) {
               e.printStackTrace();
           }
          
       }
		return null;
        
    }
    
    @PreAuthorize("@ss.hasPermi('oms:order:export')")
    @Log(title = "只锁单不导出", businessType = BusinessType.UPDATE)
    @GetMapping("/orderLock") 
    public ResponseEntity<String> orderLock( ManagerOrderQueryForm query) {
    	 long lockTime = Long.parseLong("1"+DateUtil.format(DateUtil.date(), "yyyyMMddHHssSSS")+ SecurityUtils.getUserId());
         Long qrDeptZbjId = SecurityUtils.getDeptZbjId();
         String redisKey = "order_export_lock_key"+qrDeptZbjId;
         String redisValue = "order_export_lock_value" + "_" + lockTime;
         try{
             redisService.lock(redisKey, redisValue, 60*30);
             if(qrDeptZbjId!=null) {
             	query.setDeptZbjId(qrDeptZbjId);
             }
             int num = service.lockManagerOrder(query, lockTime);
             return ResponseEntity.ok("操作成功，共"+num+"个订单");
         } catch (Exception e) {
			e.printStackTrace();
		}finally {
             try {
                 redisService.unLock(redisKey, redisValue);
             } catch (Exception e) {
                 e.printStackTrace();
             }
         }
		return null;
    }
    
 
    //@ApiOperation("导出订单表列表-锁单")
    @PreAuthorize("@ss.hasPermi('oms:order:export')")
    @Log(title = "订单表-锁单", businessType = BusinessType.EXPORT)
    @GetMapping("/exportLock") // @RequestBody
    public ResponseEntity<ExportExcel> exportLock( ManagerOrderQueryForm query) {
         long lockTime = Long.parseLong("1"+DateUtil.format(DateUtil.date(), "yyyyMMddHHssSSS")+ SecurityUtils.getUserId());
         MyEasyExcelUtil<ManagerOrderVO> myEasyExcelUtil = null;
         Long qrDeptZbjId = SecurityUtils.getDeptZbjId();
 
         String redisKey = "order_export_lock_key"+qrDeptZbjId;
         String redisValue = "order_export_lock_value" + "_" + lockTime;
         try{
             redisService.lock(redisKey, redisValue, 60*30);
             //设置导出字典
             ExcelSysDictOutUtils.setSysDictMap(ManagerOrderVO.class);
             if(qrDeptZbjId!=null) {
             	query.setDeptZbjId(qrDeptZbjId);
             }
             PageRequest pageable =  PageRequest.of(0, 1); 
             Page<ManagerOrderVO> retPage =  service.selectList(query, pageable);
             long dataSize = retPage.getTotalElements();
             ExportExcel exportExcel = new ExportExcel(JSONUtil.toJsonStr(query), "订单表数据-锁单编号"+lockTime+".xlsx", "订单数据锁单导出", lockTime, dataSize);
             myEasyExcelUtil = new MyEasyExcelUtil<ManagerOrderVO>(ManagerOrderVO.class, exportExcel);
             int pageSize = 2000;
             int leng = myEasyExcelUtil.getLength(dataSize, pageSize);
             for (int i = 0; i < leng; i++) {
                 Page<ManagerOrderVO> page =  service.selectList(query, PageRequest.of(i, pageSize),true);
                 myEasyExcelUtil.writeList(page.getContent());
  		     }
             myEasyExcelUtil.finish();
             service.lockManagerOrder(query, lockTime);
             return ResponseEntity.ok(exportExcel);
         } catch (Exception e) {
			if(myEasyExcelUtil!=null){
				myEasyExcelUtil.error(e);
			} 
			e.printStackTrace();
		}finally {
		     if(myEasyExcelUtil!=null){
 				myEasyExcelUtil.finallyClose();
 			 } 
		    
             try {
                 redisService.unLock(redisKey, redisValue);
             } catch (Exception e) {
                 e.printStackTrace();
             }
         
         }
		return null;
    }
    
    
    
    

    @ApiOperation("获取订单表详细信息")
    @PreAuthorize("@ss.hasPermi('oms:order:query')")
    @GetMapping(value = "/{id}")
    public ResponseEntity<ManagerOrderDetailVO> getInfo(@PathVariable("id") Long id) {
        return ResponseEntity.ok(service.selectById(id));
    }

    @ApiOperation("新增订单表")
    @PreAuthorize("@ss.hasPermi('oms:order:add')")
    @Log(title = "订单表", businessType = BusinessType.INSERT)
    @PostMapping
    public ResponseEntity<Integer> add(@RequestBody Order order) {
        return ResponseEntity.ok(service.insert(order));
    }

    @ApiOperation("修改订单表")
    @PreAuthorize("@ss.hasPermi('oms:order:edit')")
    @Log(title = "订单表", businessType = BusinessType.UPDATE)
    @PutMapping
    public ResponseEntity<Integer> edit(@RequestBody Order order) {
        return ResponseEntity.ok(service.update(order));
    }

//    @ApiOperation("删除订单表")
//    @PreAuthorize("@ss.hasPermi('oms:order:remove')")
//    @Log(title = "订单表", businessType = BusinessType.DELETE)
//	@DeleteMapping("/{id}")
//    public ResponseEntity<Integer> remove(@PathVariable Long id) {
//        return ResponseEntity.ok(service.deleteById(id));
//    }

    @ApiOperation("添加备注")
    @PreAuthorize("@ss.hasPermi('oms:order:note:add')")
    @Log(title = "订单表", businessType = BusinessType.UPDATE)
    @PostMapping("/merchantNote/add")
    public ResponseEntity<Integer> saveMerchantNote(@RequestBody Order order){
        return ResponseEntity.ok(service.saveMerchantNote(order));
    }

    @ApiOperation("管理后台订单发货")
    @PreAuthorize("@ss.hasPermi('oms:order:delivery')")
    @PostMapping("/deliverProduct")
    public ResponseEntity<String> delivery(@RequestBody DeliverProductForm request){
        Long userId = SecurityUtils.getUserId();
        String redisKey = "oms_order_deliverProduct" + request.getOrderId();
        String redisValue = request.getOrderId() + "_" + System.currentTimeMillis();
        try{
            redisService.lock(redisKey, redisValue, 60);
            return ResponseEntity.ok(service.deliverProduct(request, userId));
        }catch (Exception e){
            log.error("订单发货接口异常");
            throw new RuntimeException("发货失败");
        }finally {
            try{
                redisService.unLock(redisKey, redisValue);;
            }catch (Exception e){
                log.error("", e);
            }
        }
    }
    
    
//    @ApiOperation("批量设置已发货")
//    @PreAuthorize("@ss.hasPermi('oms:order:delivery')")
//    @GetMapping("/batchDeliverProductZt")
//    @Log(title = "批量设置已发货", businessType = BusinessType.UPDATE)
//    public ResponseEntity<String> batchDeliverProductZt(ManagerOrderQueryForm query){
//      Long qrDeptZbjId = SecurityUtils.getDeptZbjId();
//    	query.setDeptZbjId(qrDeptZbjId);
//	   	long lockTime = Long.parseLong("1"+DateUtil.format(DateUtil.date(), "yyyyMMddHHssSSS")+ SecurityUtils.getUserId());
//	    String redisKey = "order_export_lock_key"+qrDeptZbjId;
//	    String redisValue = "order_export_lock_value" + "_" + lockTime;
//        try{
//            redisService.lock(redisKey, redisValue, 60);
//            int num = service.batchDeliverProductZt(query);
//            return ResponseEntity.ok("操作成功，共"+num+"个订单");
//        }catch (Exception e){
//            log.error("订单发货接口异常");
//            throw new RuntimeException("批量设置发货状态失败");
//        }finally {
//            try{
//                redisService.unLock(redisKey, redisValue);;
//            }catch (Exception e){
//                log.error("", e);
//            }
//        }
//        
//    }
    
 
    @ApiOperation("订单日志")
    @GetMapping("/log/{orderId}")
    public ResponseEntity<List<OrderOperateHistoryVO>> log(@PathVariable Long orderId){
        return ResponseEntity.ok(service.log(orderId));
    }

    @PreAuthorize("@ss.hasAnyRoles('admin')")
    @ApiOperation("订单解密")
    @GetMapping("/decryptPhone/{orderId}")
    public ResponseEntity<String> decryptPhone(@PathVariable Long orderId){
        String decryptPhone = service.decryptPhone(orderId);
        return ResponseEntity.ok(decryptPhone);
    }
    
    @Autowired
    private H5OrderService h5OrderService;
    
    @ApiOperation("申请售后")
    @PreAuthorize("@ss.hasPermi('oms:order:refund')")
    @PostMapping("/applyRefund")///oms/order
    @Log(title = "后台发起退款", businessType = BusinessType.INSERT)
    public ResponseEntity<String> applyRefund(@RequestBody ApplyRefundForm applyRefundForm){
        LoginUser user = SecurityUtils.getLoginUser();
        Order orderDb = service.selectOrderById(applyRefundForm.getOrderId());
        
    	String description  = applyRefundForm.getDescription();
    	description = "后台发起退款，管理员id：" +user.getUserId() + " 姓名：" +user.getUser().getNickName() +" 备注：" + description;
    	applyRefundForm.setDescription(description);
    	
         Long qrDeptZbjId = orderDb.getDeptZbjId();
  	     String existJobInfo = redisCache.getCacheObject("order_export_lock_key"+qrDeptZbjId);
         if (StringUtils.isNotEmpty(existJobInfo)) {
        	 throw new RuntimeException("导单中，请稍后重试！");
         }
         
        String redisKey = "h5_oms_order_applyRefund_" + applyRefundForm.getOrderId();
        String redisValue = applyRefundForm.getOrderId() + "_" + System.currentTimeMillis();
        try{
            redisService.lock(redisKey, redisValue, 60);
            Order order = h5OrderService.applyRefund(applyRefundForm,true);
       
            DealWithAftersaleForm req = new DealWithAftersaleForm();
            req.setOrderId(applyRefundForm.getOrderId());
            req.setOptType(1);
            aftersaleService.dealWith(req, user.getUserId(), "后台发起退款，管理员："+user.getUser().getNickName());
            return ResponseEntity.ok("退款中，请稍后！"); 
        }catch (Exception e){
            log.error("申请售后发生异常",e);
            throw new RuntimeException(e.getMessage());
        }finally {
            try {
                redisService.unLock(redisKey, redisValue);
            } catch (Exception e) {
                log.error("", e);
            }
        }
    }
    
    
}
